﻿//************************************************************************************************************
// CoNatural.Data.dll
// Author: Roger Torres
//************************************************************************************************************
// You can use, modify, and distribute the source code and executable programs based on the source code.
// This source code is provided "as is" and without warranties as to performance or merchantability. 
// The author and/or distributors of this source code may have made statements about this source code. 
// Any such statements do not constitute warranties and shall not be relied on by the user in deciding 
// whether to use this source code. This source code is provided without any express or implied warranties 
// whatsoever. Because of the diversity of conditions and hardware under which this source code may be used, 
// no warranty of fitness for a particular purpose is offered. The user is advised to test the source code 
// thoroughly before relying on it. The user must assume the entire risk of using the source code.
//************************************************************************************************************

using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using CoNatural.Data.Helpers;
using CoNatural.Binders;

namespace CoNatural.Data.Binders {
	/// <summary>
	/// Interface implemented by command binders
	/// </summary>
	public interface ICommandBinder {
		/// <summary>
		/// The name of the command in the db system (stored procedure name)
		/// </summary>
		string DbName { get; }

		/// <summary>
		/// Creates IDbCommand from ICommand and copies input parameters
		/// </summary>
		IDbCommand CreateDbCommand(IDbProvider dbProvider, ICommand command);

		/// <summary>
		///  Copies output parameters from IDbCommand to ICommand
		/// </summary>
		void CopyOutput(IDbCommand dbCommand, ICommand command);
	}

	/// <summary>
	/// Interface implemented by data binders
	/// </summary>
	public interface IDataBinder {
		IDbProvider DbProvider { get; }
		ICommandScriptProvider ScriptProvider { get; }

		#region Model to Command
		/// <summary>
		/// Binds model to command
		/// </summary>
		/// <param name="model">The model instance.</param>
		/// <param name="command">The command instance.</param>
		void Bind(object model, ICommand command);

		/// <summary>
		/// Binds command to model
		/// </summary>
		/// <param name="command">The command instance.</param>
		/// <param name="model">The model instance.</param>
		void Bind(ICommand command, object model);

		/// <summary>
		/// Maps model to command
		/// </summary>
		/// <param name="model">The model instance.</param>
		/// <param name="command">The command instance.</param>
		IList<IMapping> Map(object model, ICommand command);

		#endregion Model to Command

		#region Command

		/// <summary>
		/// Creates ICommandBinder for ICommand
		/// </summary>
		/// <param name="command">The command instance.</param>
		/// <returns>The binder.</returns>
		ICommandBinder CreateBinder(ICommand command);

		#endregion Command

		#region Materializers 

		/// <summary>
		/// Creates materializer of records into instances of T.
		/// </summary>
		/// <typeparam name="R">The type of the target in the reader context.</typeparam>
		/// <typeparam name="T">The type of the target to be bound.</typeparam>
		/// <param name="context">The reader context.</param>
		/// <returns>The materializer.</returns>
		IBinder CreateMaterializer<R, T>(ReaderExecutionContext<R> context)
			where R : class, new()
			where T : class, new();

		#endregion Materializers
	}
}
